package GoogleServices;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import myContacts.AddressBook;
import myContacts.AddressBookHandler;
import myContacts.Contact;
import myContacts.wrapper.ContactWrapper;


import com.google.gdata.data.Link;
import com.google.gdata.data.batch.BatchOperationType;
import com.google.gdata.data.batch.BatchStatus;
import com.google.gdata.data.batch.BatchUtils;
import com.google.gdata.data.contacts.ContactEntry;
import com.google.gdata.data.contacts.ContactFeed;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.ServiceException;


/**
 * 
 * @author Rino
 *
 *  Classe che fornisce un' insieme di Api relative a Google Contact che
 *  saranno utlizzate dagli agenti
 *   
 */
public class GoogleContactCalls extends GoogleServices
{

	public GoogleContactCalls(final String username, final String password) throws AuthenticationException
	{
		super(username, password);
		// TODO Auto-generated constructor stub
	}

	public byte[] downloadPhoto(Link contactPhotoLink)
			throws ServiceException, IOException {

		Link photoLink = contactPhotoLink;

		if (photoLink != null) 
		{  
			@SuppressWarnings("deprecation")
			InputStream in = contactsService.getStreamFromLink(photoLink);

			ByteArrayOutputStream out = new ByteArrayOutputStream();

			byte[] buffer = new byte[4096];

			int read;
			while (true) {

				if ((read = in.read(buffer)) != -1) {
					out.write(buffer, 0, read);
				} else {
					break;
				}
			}

			return out.toByteArray();

		}
		return null;
	}


	public AddressBook getAllContacts() throws IOException, ServiceException
	{

		AddressBook addressBook = new AddressBook();

		//query che restituisce tutti i contatti
		ContactFeed resultFeed = contactsService.getFeed(feedUrlContact, ContactFeed.class);

		List<Contact> contacts = new ArrayList<Contact>();

		for( ContactEntry contactEntry : resultFeed.getEntries()) {

			contacts.add(ContactWrapper.getContact(contactEntry));
		}

		addressBook.setContacts(contacts);

		return addressBook;
	}

	public ContactEntry updateContact(ContactEntry contact) throws IOException, ServiceException
	{
		URL editUrl = new URL(contact.getEditLink().getHref());

		ContactEntry contactEntry = contactsService.update(editUrl, contact);
		System.out.println("Updated: " + contactEntry.getUpdated().toString());

		return contact;
	}

	public void executeBatchRequest(AddressBookHandler addressBookHandler) throws ServiceException, IOException {
		
		// Feed that holds all the batch request entries.
		ContactFeed requestFeed = new ContactFeed();

		// Create a ContactEntry for the create request.
		for( Contact createContact : addressBookHandler.getNewContacts())
		{
			ContactEntry contactEntry = ContactWrapper.getContactEntry(createContact);

			BatchUtils.setBatchId(contactEntry, "create");
			BatchUtils.setBatchOperationType(contactEntry, BatchOperationType.INSERT);

			// Insert the entries to the batch feed.
			contactEntry.setEtag("*");
			requestFeed.getEntries().add(contactEntry);
		}
		
		// Retrieve the ContactEntry to update.
		for(Contact updateContact : addressBookHandler.getUpdatedContacts())
		{
			ContactEntry contactEntry = ContactWrapper.getContactEntry(updateContact);
			
			contactEntry.setId(contactEntry.getId().replace("base", "full"));
			
			BatchUtils.setBatchId(contactEntry, "update");
			BatchUtils.setBatchOperationType(contactEntry, BatchOperationType.UPDATE);
			
			contactEntry.setEtag("*");
			requestFeed.getEntries().add(contactEntry);
		}

		// Retrieve the ContactEntry to delete.
		for(Contact deleteContact : addressBookHandler.getDeletedContacts())
		{
			ContactEntry contactEntry = ContactWrapper.getContactEntry(deleteContact);
			
			contactEntry.setId(contactEntry.getId().replace("base", "full"));
			
			BatchUtils.setBatchId(contactEntry, "delete");
			BatchUtils.setBatchOperationType(contactEntry, BatchOperationType.DELETE);

			contactEntry.setEtag("*");
			requestFeed.getEntries().add(contactEntry);
		}		

		// Submit the batch request to the server.
		ContactFeed responseFeed = contactsService.batch(feedUrlContactBatch, requestFeed);

		// Check the status of each operation.
		for (ContactEntry entry : responseFeed.getEntries()) {
			
			String batchId = BatchUtils.getBatchId(entry);
			BatchStatus status = BatchUtils.getBatchStatus(entry);
			
			Contact contact = new Contact();
			contact.setId(entry.getId().replace("full", "base"));
			
			if(batchId.equals("delete") && status.getCode()==200)
			{
				addressBookHandler.getAddressBook().getContacts().remove(contact);
			}
			else if(batchId.equals("update") && status.getCode()==200)
			{
				int i=0;
				while( i<addressBookHandler.getAddressBook().getContacts().size() && addressBookHandler.getAddressBook().getContacts().get(i).getId().equals(contact.getId()))
					i++;
				
				if(i<addressBookHandler.getAddressBook().getContacts().size())
				{
					contact = ContactWrapper.getContact(entry);
					contact.setId(contact.getId().replace("full", "base"));
					
					addressBookHandler.getAddressBook().getContacts().remove(contact);
					addressBookHandler.getAddressBook().getContacts().add(contact);
				}
					
			}
			else if(batchId.equals("create") && status.getCode()==200)
			{
				contact = ContactWrapper.getContact(entry);
				contact.setId(contact.getId().replace("full", "base"));
				
				addressBookHandler.getAddressBook().getContacts().add(contact);
			}
				
			System.out.println(batchId + ": " + status.getCode() + " (" + status.getReason() + ")");
		}
		
		addressBookHandler.flush();
	}
}
